#include "ProtocolConfigManager.h"
#include <QFile>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
#include <QXmlStreamReader>
#include <QDebug>

ProtocolConfigManager::ProtocolConfigManager(QObject *parent)
    : QObject(parent)
{
    m_defaultDeviceId = "default";
}

ProtocolConfigManager::~ProtocolConfigManager()
{
}

bool ProtocolConfigManager::loadConfig(const QString &configFilePath, const QString &deviceId)
{
    // 打开文件
    QFile file(configFilePath);
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
        qWarning() << "Failed to open config file:" << configFilePath;
        return false;
    }

    QByteArray fileContent = file.readAll();
    file.close();

    // 使用提供的设备ID或生成默认设备ID
    QString targetDeviceId = deviceId.isEmpty() ? "default" : deviceId;

    // 如果是首次加载且没有指定设备ID，则设为默认设备
    if (m_defaultDeviceId.isEmpty() && deviceId.isEmpty()) {
        m_defaultDeviceId = targetDeviceId;
    }

    // 只支持JSON配置文件
    QString fileExtension = configFilePath.split(".").last().toLower();
    if (fileExtension != "json") {
        qWarning() << "Unsupported config file format, only JSON is supported:" << fileExtension;
        return false;
    }

    bool success = parseJsonConfig(fileContent, targetDeviceId);

    if (success) {
        m_isConfigValid[targetDeviceId] = true;
        qDebug() << "Config file loaded successfully for device" << targetDeviceId << ":" << configFilePath;
        qDebug() << "Loaded" << m_binaryProtocolConfigs[targetDeviceId].size() << "binary protocol configurations";
        qDebug() << "Loaded" << m_functionProtocolConfigs[targetDeviceId].size() << "function protocol configurations";
    } else {
        m_isConfigValid[targetDeviceId] = false;
        qWarning() << "Failed to parse config file for device" << targetDeviceId << ":" << configFilePath;
    }
    return success;
}

void ProtocolConfigManager::releaseConfig(const QString &deviceId)
{
    if (deviceId.isEmpty()) {
        // 释放所有设备配置
        m_binaryProtocolConfigs.clear();
        m_functionProtocolConfigs.clear();
        m_isConfigValid.clear();
        m_defaultDeviceId.clear();
        qDebug() << "All device configs released";
    } else {
        // 释放指定设备配置
        m_binaryProtocolConfigs.remove(deviceId);
        m_functionProtocolConfigs.remove(deviceId);
        m_isConfigValid.remove(deviceId);

        // 如果释放的是默认设备，则重新设置默认设备
        if (deviceId == m_defaultDeviceId) {
            if (!m_isConfigValid.isEmpty()) {
                m_defaultDeviceId = m_isConfigValid.keys().first();
            } else {
                m_defaultDeviceId.clear();
            }
        }
        qDebug() << "Config released for device" << deviceId;
    }
}

QVariantMap ProtocolConfigManager::getBinaryProtocolConfig(int commandType, const QString &deviceId) const
{
    QString effectiveDeviceId = deviceId.isEmpty() ? m_defaultDeviceId : deviceId;
    if (effectiveDeviceId.isEmpty() && !m_binaryProtocolConfigs.isEmpty()) {
        effectiveDeviceId = m_binaryProtocolConfigs.keys().first();
    }

    if (m_binaryProtocolConfigs.contains(effectiveDeviceId) && m_binaryProtocolConfigs[effectiveDeviceId].contains(commandType)) {
        return m_binaryProtocolConfigs[effectiveDeviceId].value(commandType);
    }
    qWarning() << "Binary protocol config not found for command type:" << commandType << "and device:" << effectiveDeviceId;
    return QVariantMap();
}

QVariantMap ProtocolConfigManager::getFunctionProtocolConfig(const QString &functionName, const QString &deviceId) const
{
    QString effectiveDeviceId = deviceId.isEmpty() ? m_defaultDeviceId : deviceId;
    if (effectiveDeviceId.isEmpty() && !m_functionProtocolConfigs.isEmpty()) {
        effectiveDeviceId = m_functionProtocolConfigs.keys().first();
    }

    if (m_functionProtocolConfigs.contains(effectiveDeviceId) && m_functionProtocolConfigs[effectiveDeviceId].contains(functionName)) {
        return m_functionProtocolConfigs[effectiveDeviceId].value(functionName);
    }
    qWarning() << "Function protocol config not found for function:" << functionName << "and device:" << effectiveDeviceId;
    return QVariantMap();
}

bool ProtocolConfigManager::isConfigValid() const
{
    return !m_isConfigValid.isEmpty();
}

QVariantMap ProtocolConfigManager::getProtocolInfo(const QString &protocolName, const QString &deviceId) const
{
    QString effectiveDeviceId = deviceId.isEmpty() ? m_defaultDeviceId : deviceId;
    if (effectiveDeviceId.isEmpty() && (!m_binaryProtocolConfigs.isEmpty() || !m_functionProtocolConfigs.isEmpty())) {
        // 如果没有指定设备ID且有配置，使用第一个可用设备ID
        if (!m_binaryProtocolConfigs.isEmpty()) {
            effectiveDeviceId = m_binaryProtocolConfigs.keys().first();
        } else {
            effectiveDeviceId = m_functionProtocolConfigs.keys().first();
        }
    }

    // 检查二进制协议
    if (m_binaryProtocolConfigs.contains(effectiveDeviceId)) {
        const QMap<int, QVariantMap> &binaryConfigs = m_binaryProtocolConfigs[effectiveDeviceId];
        for (auto it = binaryConfigs.begin(); it != binaryConfigs.end(); ++it) {
            const QVariantMap &config = it.value();
            if (config.contains("name") && config["name"].toString() == protocolName) {
                QVariantMap result = config;
                result["protocolType"] = "binary";
                result["commandType"] = it.key();
                return result;
            }
        }
    }

    // 检查函数协议
    if (m_functionProtocolConfigs.contains(effectiveDeviceId)) {
        const QMap<QString, QVariantMap> &functionConfigs = m_functionProtocolConfigs[effectiveDeviceId];
        for (auto it = functionConfigs.begin(); it != functionConfigs.end(); ++it) {
            const QVariantMap &config = it.value();
            if (config.contains("name") && config["name"].toString() == protocolName) {
                QVariantMap result = config;
                result["protocolType"] = "function";
                result["functionName"] = it.key();
                return result;
            }
        }
    }

    qWarning() << "Protocol info not found for name:" << protocolName << "and device:" << effectiveDeviceId;
    return QVariantMap();
}

bool ProtocolConfigManager::parseJsonConfig(const QByteArray &data, const QString &deviceId)
{
    QJsonParseError parseError;
    QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &parseError);

    if (parseError.error != QJsonParseError::NoError) {
        qWarning() << "JSON parse error for device" << deviceId << ":" << parseError.errorString();
        return false;
    }

    if (!jsonDoc.isObject()) {
        qWarning() << "Invalid JSON format for device" << deviceId << ": root is not an object";
        return false;
    }

    QJsonObject rootObj = jsonDoc.object();

    // 解析协议数组
    if (rootObj.contains("protocols") && rootObj["protocols"].isArray()) {
        QJsonArray protocolsArray = rootObj["protocols"].toArray();
        for (int i = 0; i < protocolsArray.size(); ++i) {
            if (!protocolsArray[i].isObject()) {
                qWarning() << "Invalid protocol entry at index" << i << "for device" << deviceId;
                continue;
            }

            QJsonObject protocolObj = protocolsArray[i].toObject();
            if (!protocolObj.contains("id") || !protocolObj.contains("type")) {
                qWarning() << "Protocol missing required fields (id or type) at index" << i << "for device" << deviceId;
                continue;
            }

            int protocolId = protocolObj["id"].toInt();
            QString protocolType = protocolObj["type"].toString();

            if (protocolType == "binary") {
                // 处理二进制协议
                m_binaryProtocolConfigs[deviceId][protocolId] = protocolObj.toVariantMap();
            } else if (protocolType == "function") {
                // 处理函数协议
                if (protocolObj.contains("functionName")) {
                    QString functionName = protocolObj["functionName"].toString();
                    m_functionProtocolConfigs[deviceId][functionName] = protocolObj.toVariantMap();
                } else {
                    qWarning() << "Function protocol missing functionName at index" << i << "for device" << deviceId;
                }
            } else {
                qWarning() << "Unknown protocol type" << protocolType << "at index" << i << "for device" << deviceId;
            }
        }
    } else {
        qWarning() << "No protocols array found in config for device" << deviceId;
        return false;
    }

    return true;
}